#include "etharp.h"
#include "udp.h"

/*
***Arp发送
*/
void 
arp_output(struct netif *netif)
{
  uint8_t arp_data[30];
  Pack_arp_hdr   *arphdr=( Pack_arp_hdr   *)arp_data;
  struct pbuf *pbuf;
  /*上层协议*/
  arphdr->hwtype  =htons(Ethernet);
  /*协议层次*/
  arphdr->protocol=htons(ETHTYPE_IP);
  /*硬件地址长度*/
  arphdr->hwlen   =NETIF_MAX_HWADDR_LEN;
  /*协议地址长度*/
  arphdr->protolen=IP_MAX_PROTOCOL;
  /*Opcode*/
  arphdr->opcode  =htons(Arp_Reply);
  /*Src MAC IP*/
  for(uint8_t i=0;i<6;i++){
  arphdr->smac[i]=netif->hwaddr[i];
  arphdr->dmac[i]=netif->deshwaddr[i];
  }
  ADDR_IP4(netif->lacotip_addr,arphdr->sipaddr[0],
           arphdr->sipaddr[1],
           arphdr->sipaddr[2],
           arphdr->sipaddr[3])
  
  ADDR_IP4(netif->remotip_addr,arphdr->dipaddr[0],
           arphdr->dipaddr[1],
           arphdr->dipaddr[2],
           arphdr->dipaddr[3])

  /*申请内存*/
  pbuf=mymalloc(SRAM_IN,sizeof(struct pbuf));
  /*申请数据存储的内存*/
  pbuf->payload=mymalloc(SRAM_IN,sizeof(Pack_arp_hdr)+SIZEOF_ETH_HDR);
  /**/
  pbuf->next=NULL;
  /*通知上层应用*/
  netif->flags=ETHTYPE_ARP;
  /*本次数据的长度*/
  pbuf->len =sizeof(Pack_arp_hdr);
  /*加上报文的数据长度*/
  pbuf->data_len=pbuf->len+SIZEOF_ETH_HDR;
  /*数据需要偏移的报文长度*/
  pbuf->hdr_len=SIZEOF_ETH_HDR;
  if(pbuf !=NULL){
    /*数据打包*/
    pbuf_tack(pbuf,arp_data);
    /*传至上层*/
    eth_output(netif,pbuf);
  }
return ;
}
/*
***Arp解析
*/
static void
arp_input(struct netif *netif,struct pbuf *p)
{
    struct netif   *lnetif;
    struct eth_hdr *ethhdr;
    Pack_arp_hdr   *arthdr;
    ip_addr_t   srcipaddr,dstipaddr;
    uint16_t Opcode;
    /*eth报文*/
    ethhdr = (struct eth_hdr *)p->payload;
    /*arp报文*/
    arthdr =(Pack_arp_hdr *)((uint8_t *)ethhdr+SIZEOF_ETH_HDR);
    /*Opcode*/
    Opcode = htons(arthdr->opcode);
    /*获取目的IP,为自己*/
    IP4_ADDR(&srcipaddr,arthdr->dipaddr[0],
             arthdr->dipaddr[1],
             arthdr->dipaddr[2],
             arthdr->dipaddr[3]);
    /*存源IP，为自己*/
    IP4_ADDR(&dstipaddr,arthdr->sipaddr[0],
             arthdr->sipaddr[1],
             arthdr->sipaddr[2],
             arthdr->sipaddr[3]);
    for(lnetif=netif;lnetif != NULL;lnetif=lnetif->next){
      if(lnetif->lacotip_addr.addr==srcipaddr.addr){
        switch(Opcode){
        case Arp_Request:
          
          
          //保存远端IP到控制块
          lnetif->remotip_addr.addr=dstipaddr.addr;
          //保存远端的MAC地址
          for(uint8_t i=0;i<6;i++)
            lnetif->deshwaddr[i]= arthdr->smac[i];
          
          arp_output(lnetif); 
          break;
        case Arp_Reply:
          
          break;
        default:
          break;
        }
      }
    } 
p->payload=myfree(SRAM_IN,p->payload);
p=(struct pbuf *)myfree(SRAM_IN,p);
}

/*
***Eth
*/
uint8_t ethernet_input(struct pbuf *p, struct netif *netif)
{
   uint16_t type;
   struct eth_hdr *ethhdr=(struct eth_hdr *)p->payload;
   type=htons(ethhdr->type);
/*MAC地址过滤*/   
//   if(ethhdr->dest[0]==LL_BORADCAST&&
//      ethhdr->dest[1]==LL_BORADCAST&&
//      ethhdr->dest[2]==LL_BORADCAST&&
//      ethhdr->dest[3]==LL_BORADCAST)
//                goto Ethtype_analyse;
   /*主机字节序，与网络字节序*/
//   else if(ethhdr->dest[0]==__ArtNet_Dev.mac[0]&&
//           ethhdr->dest[1]==__ArtNet_Dev.mac[1]&&
//           ethhdr->dest[2]==__ArtNet_Dev.mac[2]&&
//           ethhdr->dest[3]==__ArtNet_Dev.mac[3])
//                goto Ethtype_analyse;

   
//p->payload=myfree(SRAM_IN,p->payload);
//p=myfree(SRAM_IN,p);//释放内存
//return 0;       //数据不对

/*处理数据类型*/
//Ethtype_analyse:
  switch(type){
    case ETHTYPE_IP:
      ip_input(netif,p);
      break;
    case ETHTYPE_ARP:
      arp_input(netif,p);
      break;
default:
  break;
  }
p->payload=myfree(SRAM_IN,p->payload);
p=(struct pbuf *)myfree(SRAM_IN,p);//释放内存
return 0;       //OK
}
/*
***eth数据包
*/
void 
eth_output(struct netif *netif,struct pbuf *p)
{
  uint8_t ETH_HDR[14];
  struct eth_hdr *ethhdr=(struct eth_hdr *)ETH_HDR;
  for(uint8_t i=0;i<6;i++){
  /*源地址*/
  ethhdr->src[i]=netif->hwaddr[i];
  /*目标地址*/
  ethhdr->dest[i]=netif->deshwaddr[i];
  }
  switch(netif->flags){
    case ETHTYPE_ARP:
        ethhdr->type=htons(ETHTYPE_ARP);
      break;
    case ETHTYPE_IP:
        ethhdr->type=htons(ETHTYPE_IP);
      break;
  default:
    break;
  }
  memcpy(p->payload,ETH_HDR,SIZEOF_ETH_HDR);
  netif->output(netif,p);
  
}
